from multineuro.sprite.button import Button
from multineuro.sprite import ImgSprite
import logging
from multineuro.sprite.textsprite import TextSprite
from tom.configuration import CONGRATS_PICTURE

class UnsupportedType(Exception):
    pass

class Screen(object):


    def _begin(self):
        self.hide()
        self.active_sprites = self.start_sprites
        self.show()

    def _end(self):
        if self.root:
            self.congrats.show()
        else:
            self.callback()

    def _root_initialize(self):
        "Adds a White Splash at the beginning showing the game name"
        self.splash = TextSprite(self.name, self._begin)
        self.congrats = Button((0, 0), lambda _:self.callback(), CONGRATS_PICTURE)
        self.congrats.center()
        self.start_sprites = self.active_sprites
        self.active_sprites = [self.splash]

    def __init__(self, conf, callback, logger, root=False):
        self.callback = callback
        self.logger = logger
        self._sprites = []
        self.active_sprites = []
        self.type = conf['type']
        self.name = conf['name']

        self.root = root
        initialize = getattr(self, '_' + self.type + '_configuration')
        initialize(conf)

        if self.root:
            self._root_initialize()
        self.hide()

    def _choose_configuration(self, conf):
        for sprite_conf in conf['button_sprites']:
            self._sprites.append(Button(sprite_conf['position'],
                                        self._save_answer,
                                        resource=sprite_conf['resource'],
                                        val=sprite_conf['val']))

        for sprite_conf in conf['normal_sprites']:
            self._sprites.append(ImgSprite(sprite_conf['resource'],
                                           sprite_conf['position']))

        self.active_sprites = self._sprites

    def _full_configuration(self, conf):
        self.current_sprite = 0
        for sprite_conf in conf['full_sprites']:
            sprite = Button((0, 0),
                            lambda _:self._next_full(),
                            resource=sprite_conf['resource'])
            sprite.set_full_size()
            self._sprites.append(sprite)

        self.active_sprites = [self._sprites[0]]

    def _nested_configuration(self, conf):
        self.current_sprite = 0
        for screen_conf in conf['screens']:
            self._sprites.append(Screen(screen_conf, self._next_full, self.logger))

        self.active_sprites = [self._sprites[0]]

    def _save_answer(self, val):
        logging.debug('Save answer.')
        self.logger.save_answer(self.name, val)
        self.hide()
        self._end()

    def _next_full(self):
        logging.debug('next_full ' + self.type)
        self.current_sprite += 1
        self.hide()
        if self.current_sprite < len(self._sprites):
            self.active_sprites = [self._sprites[self.current_sprite]]
            self.show()
        else:
            self._end()

    def sprites(self):
        """ Get this screen sprites. """
        if self.type == 'nested':
            sprites = [sprite
                       for screen_ in self._sprites
                       for sprite in screen_.sprites()]
        else:
            sprites = self._sprites[:]

        if self.root:
            sprites.append(self.splash)
            sprites.append(self.congrats)
        return sprites

    def show(self):
        "Show this screen"
        for sprite in self.active_sprites:
            logging.debug('Showing: ' + sprite.__class__.__name__)
            sprite.show()

    def hide(self):
        "Hide this screen"
        for sprite in self.sprites():
            logging.debug('Hiding: ' + sprite.__class__.__name__)
            sprite.hide()

